﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Wedo.Utility.Cache;
using System.Xml.Linq;
using System.Data;
using System.Data.OleDb; 
namespace Wedo.Utility.File
{
    /// <summary>
    /// 根据索引获取对象列表
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ObjectFromExcelFileByIndex<T> : ObjectFromFile<T>, IDisposable where T : class,new()
    {
        public ObjectFromExcelFileByIndex()
        {
            IsRemoveEmpty = true;
        }

        private string _filePath;
 
        protected OleDbConnection conn;

        protected string strConn;

        protected DataTable _Datatable;

       
        public string FilePath { get{ return _filePath;}}

        protected OleDbConnection GetConnection()
        {
            if (conn == null)
            {
                string ext = System.IO.Path.GetExtension(FilePath).ToLower();
                if (ext == ".xlsx")
                    strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + FilePath + ";Extended Properties='Excel 12.0;HDR=NO;IMEX=1;';";
                else if (ext == ".xls")
                    strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + FilePath + ";Extended Properties='Excel 8.0;HDR=NO;IMEX=1;';";

                conn = new OleDbConnection(strConn);
                conn.Open();
            }

            return conn;
        }

        public bool IsRemoveEmpty { get; set; }


        public DataTable DataTable { get { return _Datatable; } }

        protected Type tType;

        protected ObjectMapping mapping;

        /// <summary>
        /// 从对象中获取数据列表
        /// </summary>
        /// <param name="name">对象名称</param>
        /// <param name="filepath">文件路径</param>
        /// <returns></returns>
        public override IEnumerable<T> GenerateObjectsFromFile(string name, string filepath)
        {
            filepath.CheckNull();
            _filePath = filepath;

            if (!System.IO.File.Exists(_filePath))
            {
                ErrMsgs.Add(string.Format("指定的文件{0}不存在", _filePath));
                return null;
            }
            mapping = GetMappingByName(name);
            if (mapping == null)
                return null;
            if (string.IsNullOrWhiteSpace(mapping.Splitter))
            {
                ErrMsgs.Add("请指定需要处理的Sheet的名称列表");
                return null;
            }
            var sheetNames = GetFirstSheetName();
            _Datatable = GetDataTableFromExcel(sheetNames);

            List<T> list = new List<T>();

            tType = typeof(T);

            int StartIndex = mapping.StartIndex;

            for (int i = StartIndex; i < _Datatable.Rows.Count; i++)
            {
                try
                {
                    T inst = Parse(_Datatable.Rows[i]);
                    if (inst != null && Filter(inst))
                    {
                        list.Add(inst);
                    }
                }
                catch (Exception ex)
                {
                    continue;  
                }
            }
            return list;
        }

        public virtual DataTable GetDataTableFromExcel(string sheetname)
        {
            DataTable dt = new DataTable();

            OleDbDataAdapter adapter = new OleDbDataAdapter(string.Format("SELECT * FROM [{0}]", sheetname), conn);
            adapter.Fill(dt);
            return dt;
        }

        public virtual T Parse( DataRow row)
        {
            T inst = new T();
            foreach (var item in mapping.Properties)
            {
                SetValue(item, row, inst);
            }
            return inst;
        }


        public virtual List<string> ExcelSheetName()
        {
            List<string> al = new List<string>();

            DataTable sheetNames = GetConnection()
                .GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
            foreach (DataRow dr in sheetNames.Rows)
            {
                al.Add(dr[2].ToString());
            }
            return al;
        }

        public string GetFirstSheetName()
        {
            return ExcelSheetName().FirstOrDefault();
        }

        protected virtual bool Filter(T model)
        {
            return model != null;
        }

        public void Dispose()
        {
            if (conn != null)
                conn.Close();
        }

        protected virtual void SetValue(ObjectMappingItem item, DataRow row, T inst)
        {
            try
            {
                object val = null;
                int index = 0;
                if (int.TryParse(item.FileTitle, out index))
                {
                    string strVal =RemoveEmpty( row[index].ToString());
                    val = GetValue(item.PropertyType, strVal);
                }
                else
                {
                    string strVal = RemoveEmpty(row[item.FileTitle].ToString());
                    val = GetValue(item.PropertyType,strVal);
                }
                tType.GetProperty(item.PropertyName).SetValue(inst, val, null);
            }
            catch (Exception ex)
            {
                //ErrMsgs.Add(ex.Message);
            }
        }

        protected virtual string RemoveEmpty(string val)
        {
            val = val ?? "";
            if (IsRemoveEmpty)
            {
                val = val.Trim();
            }
            return val;
        }
    }
}
